go语言yaml各个结构嵌套 golang struct interface 嵌套

您所在的位置:网站首页 yaml语法 go go语言yaml各个结构嵌套 golang struct interface 嵌套

go语言yaml各个结构嵌套 golang struct interface 嵌套

2023-07-12 17:24| 来源: 网络整理| 查看: 265

Go中的struct

struct用来自定义复杂数据结构,相当于其他面向对象语言中的Class。

struct里面可以包含多个字段(属性)struct类型可以自定义方法,注意和函数的区分:方法有一个接受对象,而函数没有struct类型是值类型struct类型可以嵌套Go语言没有class类型,只有struct类型struct声明

语法: type 标识符 struct{ field1 type field2 type } 如:

type Student struct{ Name string Age int Score int }struct定义的三种形式var stu Student var stu *Student = new(Student) var stu *Student = &Student{}

其中,后两种返回的都是指向结构体的指针,访问形式如下:stu.Name、stu.Age和stu.Score或者 (*stu).Name、(*stu).Age、(*stu).Score。

struct的内存布局

struct中的所有字段在内存是连续的,布局如下:

go语言yaml各个结构嵌套 golang struct interface 嵌套_go语言yaml各个结构嵌套

struct工厂模式

golang中的struct没有构造函数,一般可以使用工厂模式来解决这个问题。

package model import "fmt" type student struct { name string age int } func NewStudent(name string, age int) *student { return &student{ name: name, age: age, } } func (s student)Print() { fmt.Println(s.name, s.age) }package main import ( "golang_learning/model" "fmt" "strings" ) func main() { s := model.NewStudent("sam", 18) s.Print() fmt.Println(strings.Repeat("*", 10)) }struct中的tag

我们可以为struct中的每个字段,写上一个tag。这个tag可以通过反射的机制获取到,最常用的场景就是json序列化和反序列化。

type student struct { Name string "this is name field" Age int "this is age field" }

还有一种场景是,由于golang中的字段大写才能导出,到与其他语言交互时,字段名多为小写,这个时候也可以使用tag来解决。

type student struct { Name string "name" Age int "age" }struct中的匿名字段type Wheel struct { Name string Size int } type Car struct { Wheel Comp string Date time.Time int }字段冲突的处理

只要冲突的字段不再同一个级别,就不会panic;可以通过明确指定来访问。

type Wheel struct { Name string Size int } type Car struct { Wheel Comp string Date time.Time Size int }w := Wheel{"w", 1} c := Car{w, "auto", time.Now(), 20} fmt.Println("%v", w) fmt.Println("%v", c) fmt.Println(c.Size) fmt.Println(c.Wheel.Size) // 20 // 1golang中的方法

Golang中的方法是作用在特定类型的变量上,因此自定义类型,都可以有方法,而不仅仅是struct。如:

package main import ( "fmt" ) type Int int func (i Int)print() { fmt.Println(i) } func main() { i := Int(99) i.print() } // 99

定义:func (recevier type) methodName(参数列表)(返回值列表){} 另外,方法的访问控制,通过大小写控制。

方法和函数的区别:

函数调用: function(variable, 参数列表)方法:variable.function(参数列表)指针receiver vs 值receiver

结构体是值类型的,如果需要修改其内部的值,需要使用指针。

继承和组合模拟继承

如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问匿名结构体的方法,从而实现了继承。

多重继承

如果一个struct嵌套了多个匿名结构体,那么这个结构可以直接访问多个匿名结构体的方法,从而实现了多重继承。

组合

如果一个struct嵌套了另一个有名结构体,那么这个模式就叫组合。

String()方法

如果一个变量实现了String()这个方法,那么fmt.Println默认会调用这个 变量的String()进行输出。

package main import ( "fmt" "strconv" ) type student struct{ name string age int } func (s student)String() string{ return "name: " + s.name + ", age: " + strconv.Itoa(s.age) } func main() { s := student{"lee", 18} fmt.Println(s) fmt.Printf("%s", s) } // name: lee, age: 18 // name: lee, age: 18接口

Interface类型可以定义一组方法,但是这些不需要实现。并且interface不能 包含任何变量。

接口的定义

interface类型默认是一个指针

type example interface{ Method1(参数列表) 返回值列表 Method2(参数列表) 返回值列表 ... } var a example a.Method1()接口实现golang中的接口,不需要显示的实现。只要一个变量,含有接口类型中的所有方法,那么这个变量就实现这个接口。因此,golang中没有implement类似的关键字如果一个变量含有了多个interface类型的方法,那么这个变量就实现了多个接口如果一个变量只含有了1个interface的方部分方法,那么这个变量没有实现这个接口多态

一种事物的多种形态,都可以按照统一的接口进行操作

接口嵌套

一个接口可以嵌套在另外的接口,比如:

type ReadWrite interface { Read(b int) bool Write(b int) bool } type Lock interface { Lock() Unlock() } type File interface { ReadWrite Lock Close() }类型断言

由于接口是一般类型,不知道其具体类型,如果要转换成具体类型,可以使用下面的方法进行转换:

var t int var x interface{} x = t y, ok := x.(int) // 转成intfunc classifier(items ...interface{}) { for i, x := range items { switch x.(type) { case bool: fmt.Printf("param #%d is a bool\n", i) case float64: fmt.Printf("param #%d is a float64\n", i) case int, int64: fmt.Printf("param #%d is an int\n", i) case nil: fmt.Printf("param #%d is nil\n", i) case string: fmt.Printf("param #%d is a string\n", i) default: fmt.Printf("param #%d’s type is unknown\n", i) } } }空接口

空接口没有任何方法,所以所有类型都实现了空接口。

var a int var b interface{} b = a

判断一个变量是否实现了指定接口:

type Stringer interface { String() string } var v MyStruct if sv, ok := v.(Stringer); ok { fmt.Printf("v implements String():%s\n", sv.String()) }

变量slice和接口slice之间赋值操作

变量slice和接口slice之间赋值操作,应该使用for range

var a []int var b []interface{} // b = a //error!!! for index, value := range a{ b[index] = value } fmt.Println(b)



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3